/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.cast.teseg.graficoJung;


import edu.cast.teseg.modelo.Individuos;
import edu.cast.teseg.modelo.RedSocial;
import edu.cast.teseg.modelo.Relaciones;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.util.Random;
import org.apache.commons.collections15.Transformer;

import java.util.Iterator;
import java.util.TreeMap;



/**
 *
 * @author edgarin
 */
public class GraficoGrafo {      
  // Graph<Individuos, Relaciones> grafo;
    private Graph<Integer, String> grafo;
    private int numIndividuos;
    private double probReleaciones;
    private VisualizationViewer<Integer,String> vv;
    private int numRelaciones;
    private RedSocial redGL;
    

    //*** metodo para inicar el grafo ***//
    public void iniciarGraficoGrafo(){}
    
    //***  metodo para generar un numero aleatorio ***//
    public int generarNumeroAleatorio(){
        
        int aleatorio = (int) (Math.random()*10+1);
        return aleatorio;
    }
    
    //*** metodo que genera un grafo aleatorio ***//
    public void generarGrafoAleatorio(){
        
        int totalIndividuos = generarNumeroAleatorio();        
        while(totalIndividuos!=0){
            grafo.addVertex((Integer)totalIndividuos);           
            totalIndividuos--;
       }
        
        int copiaTotalVertices = grafo.getVertexCount();        
        while(copiaTotalVertices!=0){             
            grafo.addEdge("Edge-"+copiaTotalVertices, (int)(Math.random()*grafo.getVertexCount()), (int) (Math.random()*grafo.getVertexCount()) ); // Note that Java 1.5 auto-boxes primitives          
            copiaTotalVertices--;
       }
       
    }
    
    //*** metodo que retorna un grafo ***//
    public Graph<Integer, String> getGrafo() {
        return this.grafo;
    }
    
    //*** metodo que inicia el grafo con el numero de vertices y aristas ***//
    public void iniciarGr(int numVertices, double numAristas) throws Exception {
        grafo = new SparseMultigraph<Integer, String>();
        redGL = new RedSocial();
        numRelaciones = 0;
        numIndividuos = numVertices;
        probReleaciones = numAristas;
        Random randomv = new Random();
        int degree[] = new int [numIndividuos];
        int adjacencyM[][] = new int [numIndividuos+1][numIndividuos+1];
        
        for (int i = 0; i < numIndividuos; i++){
         grafo.addVertex(i);
         redGL.setIndividuo(i, "Nombre "+i);
        }
        
        for (int i1 = 0; i1 < numIndividuos -1 ;i1++){
            for  (int i2 = i1+1 ; i2 < numIndividuos;i2++){
                if ( probReleaciones >= randomv.nextDouble() ){
                    adjacencyM[i2][i1]=1;
                    numRelaciones++;
                    degree[i1]++;
                    degree[i2]++;
                    grafo.addEdge("Edge-"+numRelaciones, i1, i2);
                    redGL.setRelaciones("E-"+numRelaciones, i1, i2);
                    }
                }
            }
        this.redGL.setMatrizAdj();
        this.redGL.cargarMatriz();
        configurarGrafo(grafo); 
    }
    
    //*** metodo que retorna un objeto VisualizarViewer ***//
    public VisualizationViewer<Integer, String> getVv() {
        return vv;
    }
    
    //*** metodo que retorna el numero de aristas ***//
    public int getNumofedgesc() {
        return numRelaciones;
    }
    
    //*** metodo para configurar los colores del grafo ***//
    private void configurarGrafo(Graph grafo){
        CircleLayout capaSalida = new CircleLayout(grafo);
        capaSalida.setSize(new Dimension(300, 300));
        vv = new VisualizationViewer<Integer,String>(capaSalida);
        vv.setPreferredSize(new Dimension(350,350));
        // Setup up a new vertex to paint transformer...
        Transformer<Integer,Paint> vertexPaint = new Transformer<Integer,Paint>() {
            @Override
            public Paint transform(Integer i) {
                return Color.GREEN;
            }
        };
        // Show vertex and edge labels
        vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
        vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
        vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
        // Create a graph mouse and add it to the visualization component
        DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
        gm.setMode(ModalGraphMouse.Mode.TRANSFORMING);
        vv.setGraphMouse(gm);    
    }
    
    //***  metodo para sacar los vertices y aristas del grafo y enviarlos a pintar ***//
    public void dibujaGrafoArchivo(RedSocial grafoRed) {
        grafo = new SparseMultigraph<Integer, String>();
        TreeMap relaciones = grafoRed.getRelaciones();
        TreeMap individuos = grafoRed.getIndividuos();
        
        for (Iterator it = individuos.values().iterator(); it.hasNext();) {
            Individuos individuo = (Individuos)it.next();
            grafo.addVertex(individuo.getId());
        }
        
        for (Iterator it = relaciones.values().iterator(); it.hasNext();) {
            Relaciones relacion = (Relaciones)it.next();
             grafo.addEdge(relacion.getId(), relacion.getOrigen(), relacion.getDestino());
        }

        configurarGrafo(grafo);
    }
    
    ///*** metodo que retorna las aristas a ser guardadas ***//
    public String getAristas(){
      String rel="";
        for (Iterator it = redGL.getRelaciones().values().iterator(); it.hasNext();) {
            Relaciones relacion = (Relaciones)it.next();             
            rel += (""+ relacion.getOrigen() +" "+ relacion.getDestino())+"l";    
        }
        return rel;
  }

    public RedSocial getRedGL() { return redGL; }
  
}